<!DOCTYPE html>
<html>
<head>
    <title>网络设备扫描</title>
	<!-- 引入Bootstrap CSS -->
 
<!-- 引入Bootstrap JS 和 Popper.js (Bootstrap的依赖) -->
    <script src="jquery-3.6.0.min.js"></script>

	<style>
	
	
.list-table {
  width: 100%;
  color: #fff;
  background-color: #1a2b3c;
  border-collapse: separate;
  border: 1px solid #6d6a6a; }
  .list-table.fixed {
    table-layout: fixed; }
  .list-table thead th {
    height: 100%;
    overflow: hidden;
	background-color: #2c3e50;
    border-bottom: 2px solid #2980b9;
    color: #737373;
    white-space: nowrap;
    vertical-align: bottom; }
    .list-table thead th z-vertical {
      display: inline-block;
      position: relative;
      max-height: 150px;
      min-width: 22px;
      overflow: hidden;
      text-overflow: ellipsis;
      line-height: 22px; }
    .list-table thead th .arrow-up {
      margin-left: 3px;
      border-bottom-color: #2980b9; }
    .list-table thead th .arrow-right {
      margin-left: 3px;
      border-left-color: #2980b9; }
    .list-table thead th .arrow-down {
      margin-left: 3px;
      border-top-color: #2980b9; }
    .list-table thead th a {
      display: block;
      position: relative;
      margin: -1em;
      padding: 1em;
      border: 0;
      transition: background-color 0.2s ease-out; }
      .list-table thead th a:hover, .list-table thead th a:focus, .list-table thead th a:active {
        text-decoration: none;
        background-color: #2980b9; }
  .list-table tbody tr.hidden {
    display: none; }
  .list-table tbody tr:last-child th,
  .list-table tbody tr:last-child td {
    border-bottom-style: none; }
  .list-table tbody tr:not(.hover-nobg):not(.row-selected):hover {
    background-color: #636e89; }
  .list-table tbody tr.row-selected {
    background-color: #2f280a; }
  .list-table tbody th.table-info,
  .list-table tbody td.table-info {
    color: #737373; }
  .list-table tbody th.list-table-actions,
  .list-table tbody td.list-table-actions {
    text-align: right;
    white-space: nowrap; }
  .list-table th,
  .list-table td {
    position: relative;
    padding: 6px 5px;
    line-height: 18px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid #2980b9; }
    .list-table th.second-col,
    .list-table td.second-col {
      width: 20px;
      padding-left: 0;
      padding-right: 0;
      text-align: center; }
  .list-table.sticky-header thead {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: #1a2b3c; }
  .list-table.sticky-footer tfoot {
    position: sticky;
    bottom: 0;
    z-index: 1;
    background: #1a2b3c; }
    .list-table.sticky-footer tfoot tr:first-of-type td, .list-table.sticky-footer tfoot tr:first-of-type th {
      border-top: 2px solid #1a2b3c;
      border-bottom-style: none; }
  .list-table .list-table-footer {
    border-bottom: 0;
    color: #737373;
    text-align: right; }
    .list-table .list-table-footer:hover {
      background-color: #1a2b3c; }
  .list-table .action-container {
    display: flex;
    width: 100%; }
    .list-table .action-container .link-action {
      height: 16px;
      min-width: 1ch; }
    .list-table .action-container .rel-container {
      display: flex; }
    .list-table .action-container .separator {
      flex-shrink: 0;
      margin-right: 4px; }
  .list-table .latest-values,
  .list-table .opdata {
    max-width: 300px; }
  .list-table .checkbox-radio {
    margin: 1px 0; }
    .list-table .checkbox-radio + label {
      display: inline-block;
      margin: 1px 0;
      line-height: 1;
      vertical-align: top; }
      .list-table .checkbox-radio + label span {
        margin: 0; }
  .list-table .wordbreak {
    white-space: normal;
    overflow: hidden;
    text-overflow: ellipsis; }
  .list-table.compact-view td {
    padding-top: 2px;
    padding-bottom: 2px;
    border-bottom: 0;
    box-shadow: inset 0 -1px 0 0 rgba(242, 242, 242, 0.1);
    white-space: nowrap; }
    .list-table.compact-view td .rel-container span {
      margin: 0; }
    .list-table.compact-view td.nowrap {
      text-overflow: clip; }
  .list-table.no-data tbody tr td {
    height: auto;
    color: #737373;
    text-align: center; }
    .list-table.no-data tbody tr td:hover {
      background-color: #1a2b3c; }
  .list-table.no-data tbody tr .no-data-message[class^="zi-"], .list-table.no-data tbody tr .no-data-message[class*=" zi-"] {
    margin-top: 100px;
    margin-bottom: 100px; }

.list-table .btn-icon,
.list-table .icon,
.list-table .link-action {
  vertical-align: top; }
  .list-table .btn-icon:not(.no-indent):not(:first-child),
  .list-table .icon:not(.no-indent):not(:first-child),
  .list-table .link-action:not(.no-indent):not(:first-child) {
    margin-left: 5px; }
.list-table .icon {
  border-radius: 2px; }
.list-table .btn-small,
.list-table .problem-icon-link,
.list-table .status-container,
.list-table .entity-count,
.list-table .tag {
  margin-top: 1px;
  margin-bottom: 1px;
  vertical-align: top; }

.list-table thead th.column-tags-1 {
  width: 75px; }
  @media screen and (min-width: 1200px) {
    .list-table thead th.column-tags-1 {
      width: 106px; } }
  @media screen and (min-width: 1400px) {
    .list-table thead th.column-tags-1 {
      width: 137px; } }
  @media screen and (min-width: 1600px) {
    .list-table thead th.column-tags-1 {
      width: 168px; } }
.list-table thead th.column-tags-2 {
  width: 124px; }
  @media screen and (min-width: 1200px) {
    .list-table thead th.column-tags-2 {
      width: 186px; } }
  @media screen and (min-width: 1400px) {
    .list-table thead th.column-tags-2 {
      width: 248px; } }
  @media screen and (min-width: 1600px) {
    .list-table thead th.column-tags-2 {
      width: 310px; } }
.list-table thead th.column-tags-3 {
  width: 173px; }
  @media screen and (min-width: 1200px) {
    .list-table thead th.column-tags-3 {
      width: 266px; } }
  @media screen and (min-width: 1400px) {
    .list-table thead th.column-tags-3 {
      width: 359px; } }
  @media screen and (min-width: 1600px) {
    .list-table thead th.column-tags-3 {
      width: 452px; } }
.list-table.compact-view .tag {
  max-width: 40px; }
  @media screen and (min-width: 1200px) {
    .list-table.compact-view .tag {
      max-width: 71px; } }
  @media screen and (min-width: 1400px) {
    .list-table.compact-view .tag {
      max-width: 102px; } }
  @media screen and (min-width: 1600px) {
    .list-table.compact-view .tag {
      max-width: 133px; } }

.hintbox-wrap .tag {
  cursor: pointer; }
  .hintbox-wrap .tag:last-child {
    margin-right: 0; }

.list-table .timeline-date,
.list-table .timeline-axis,
.list-table .timeline-td {
  border-bottom-color: transparent; }
.list-table .timeline-date {
  text-align: right;
  white-space: nowrap; }
.list-table .timeline-axis,
.list-table .timeline-th,
.list-table .timeline-td {
  position: relative;
  padding: 0;
  width: 6px; }
.list-table .timeline-axis::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: -1px;
  width: 2px;
  background-color: #aad7f0; }
.list-table .timeline-dot::after,
.list-table .timeline-dot-big::after {
  content: '';
  position: absolute;
  right: -3px;
  width: 4px;
  height: 4px;
  border-radius: 50%; }
.list-table .timeline-dot::after {
  top: 10px;
  background-color: #69808d;
  border: 2px solid #1a2b3c; }
.list-table .timeline-dot-big::after {
  top: 11px;
  background-color: #1a2b3c;
  border: 2px solid #69808d; }

.list-table .problem-expand-td {
  border-bottom-color: transparent; }
.list-table .problem-nested:not([class*='flh-']):not(.row-selected) {
  background-color: #1e1e1e; }
  .list-table .problem-nested:not([class*='flh-']):not(.row-selected) td,
  .list-table .problem-nested:not([class*='flh-']):not(.row-selected) .timeline-axis,
  .list-table .problem-nested:not([class*='flh-']):not(.row-selected) .timeline-td {
    border-bottom-color: #1e1e1e; }
.list-table .problem-nested-small {
  font-size: 11px; }
  .list-table .problem-nested-small .tag {
    font-size: 12px; }
.list-table.compact-view .problem-nested:not([class*='flh-']):not(.row-selected) td,
.list-table.compact-view .problem-nested:not([class*='flh-']):not(.row-selected) .timeline-axis,
.list-table.compact-view .problem-nested:not([class*='flh-']):not(.row-selected) .timeline-td {
  border-bottom-style: none; }
.list-table.compact-view [class*='flh-']:not(.row-selected):not(:hover) a,
.list-table.compact-view [class*='flh-']:not(.row-selected):not(:hover) td,
.list-table.compact-view [class*='flh-']:not(.row-selected):not(:hover) sup {
  color: #000000; }
.list-table.compact-view [class*='flh-']:not(.row-selected):not(:hover) .link-alt {
  border-bottom-color: #000000; }
.list-table.compact-view [class*='flh-']:not(.row-selected):not(:hover) .tag {
  color: #ffffff;
  background-color: #4f4f4f; }
.list-table.compact-view [class*='flh-']:not(.row-selected):not(:hover) .btn-icon,
.list-table.compact-view [class*='flh-']:not(.row-selected):not(:hover) .icon {
  background-color: #1a2b3c; }
.list-table.compact-view [class*='flh-']:not(.row-selected):not(:hover) .entity-count {
  margin-top: 0;
  margin-bottom: 0;
  border: 1px solid #1a2b3c; }

		.modal-backdrop {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.6);
            z-index: 1000;
            backdrop-filter: blur(3px); /* 毛玻璃效果 */
            animation: fadeIn 0.3s ease-out;
        }
        
        /* 模态框容器 */
        .modal-container {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%) scale(0.95);
            background: #fff;
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.25);
            z-index: 1001;
            max-width: 600px;
            width: 90%;
            max-height: 95vh;
            overflow-y: auto;
            animation: scaleIn 0.3s ease-out forwards;
        }
		
        .modal-content {
            background-color: #fefefe;
            margin: 15% auto;
            padding: 20px;
            border: 1px solid #888;
            width: 80%;
            max-width: 500px;
        }
        
        /* 关闭按钮 */
        .modal-close {
            position: absolute;
            top: 20px;
            right: 20px;
            width: 32px;
            height: 32px;
            cursor: pointer;
            opacity: 0.7;
            transition: opacity 0.2s, transform 0.2s;
        }
        
        .modal-close:hover {
            opacity: 1;
            transform: rotate(90deg);
        }
        
        .modal-close::before, 
        .modal-close::after {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            width: 20px;
            height: 2px;
            background: #777;
        }
        
        .modal-close::before {
            transform: translate(-50%, -50%) rotate(45deg);
        }
        
        .modal-close::after {
            transform: translate(-50%, -50%) rotate(-45deg);
        }
        
        /* 标题样式 */
        .modal-title {
            margin-top: 0;
            color: #2c3e50;
            font-weight: 600;
            font-size: 1.4rem;
            padding-bottom: 15px;
            border-bottom: 1px solid #eee;
        }
        
        /* 内容区域 */
        .modal-body {
            line-height: 1.6;
            color: #34495e;
            margin: 20px 0;
            font-size: 1.05rem;
        }
        
        /* 底部按钮 */
        .modal-footer {
            text-align: right;
            padding-top: 20px;
            border-top: 1px solid #eee;
        }
        
        .modal-btn {
            padding: 10px 24px;
            border-radius: 6px;
            cursor: pointer;
            font-weight: 500;
            border: none;
            margin-left: 10px;
            transition: all 0.2s;
        }
        
        .btn-confirm {
            background: #3498db;
            color: white;
        }
        
        .btn-cancel {
            background: #e0e0e0;
            color: #555;
        }
        
        .btn-confirm:hover {
            background: #2980b9;
            transform: translateY(-2px);
        }
        
        .btn-cancel:hover {
            background: #d0d0d0;
            transform: translateY(-2px);
        }
        
        /* 动画效果 */
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        
        @keyframes scaleIn {
            from { transform: translate(-50%, -50%) scale(0.95); opacity: 0; }
            to { transform: translate(-50%, -50%) scale(1); opacity: 1; }
        }
        
        @keyframes fadeOut {
            from { opacity: 1; }
            to { opacity: 0; }
        }
        
        /* 响应式设计 */
        @media (max-width: 576px) {
            .modal-content {
                padding: 20px;
            }
            
            .modal-title {
                font-size: 1.2rem;
            }
            
            .modal-btn {
                padding: 8px 16px;
                margin-top: 10px;
                width: 100%;
                display: block;
                margin-left: 0;
            }
        }
    </style>
	<script>

		$(document).ready(function() {
			// 打开模态框
			$(".install").click(function() {
				$("#modalBackdrop, #modalContainer").fadeIn(300);
				var ip = $(this).data('ip'); // 获取按钮上的数据属性值作为标题
				var netType = $(this).data('type');
				$("#myModalLabel").text("请输入IP为："+ip+"的设备的登录信息")
				$('#iptext').text(ip); // 设置模态框标题为获取到的值
				$('#netType').val(netType);
				$('body').css('overflow', 'hidden'); // 防止背景滚动
				$("#modalContainer").show()
				updateInputs()
			});
	
			// 关闭模态框（关闭按钮）
			$("#closeModal, #cancelBtn").click(closeModal);
			
			// 关闭模态框（点击背景）
			$("#modalBackdrop").click(closeModal);
			
			// 关闭模态框（ESC键）
			$(document).keydown(function(e) {
				if (e.key === "Escape") {
					closeModal();
				}
			});
			
			// 关闭函数
			function closeModal() {
				$("#modalContainer").animate({opacity: 0}, 300, function() {
					$(this).hide();
				});
				$("#modalBackdrop").fadeOut(300);
				$('body').css('overflow', 'auto');
			}
				
			// 关闭模态框（确认按钮） 提交表单
			$("#confirmBtn").click(function(e) {
				e.preventDefault(); // 阻止表单的默认提交行为
				const ip = $("#iptext").text();
				const username = $("#name").val()
				const password = $("#pwd").val()
				const netType = $("#netType").val()
				if(netType ==='0'){
					loginToLinux(ip,username,password)
				} else {
					const community = $("#community").val()
					const zabbixServer = $("#zabbixServer").val()
					const protocol = $('input[name="protocol"]:checked').val()
					loginToNetwork(ip, username, password, community, zabbixServer, protocol)
				}
			});
		});
		function loginToLinux(ip,username,password) {
			if (!username) return;
			if (!password) return;

			fetch('ssh_login.php', {
				method: 'POST',
				headers: {'Content-Type': 'application/json'},
				body: JSON.stringify({ ip, username, password })
			})
			.then(res => res.json())
			.then(data => {
				if (data.success) {
					alert("登录成功！");
					if (confirm("是否推送 Zabbix Agent 安装脚本？")) {
						fetch('push_agent.php', {
							method: 'POST',
							headers: {'Content-Type': 'application/json'},
							body: JSON.stringify({ ip, username, password })
						})
						.then(res => res.json())
						.then(result => {
							alert(result.success ? "安装成功" : "安装失败：" + result.error);
						});
					}
					closeModal();
				} else {
					alert("登录失败：" + data.error);
				}
			});
		}

		function showWindowsLoginTip() {
			alert('请打开本地远程桌面工具，登录服务器，安装 Zabbix Agent');
		}
		function loginToNetwork(ip, username, password, community, zabbixServer, protocol) {
			//const username = prompt("请输入 " + ip + " 的用户名：");
			if (!username) return;

			//const password = prompt("请输入密码：");
			if (!password) return;

			//const community = prompt("请输入 SNMP community（如 public）：");
			if (!community) return;

			//const zabbixServer = prompt("请输入 Zabbix Server 地址：");
			if (!zabbixServer) return;

			//const protocol = confirm("点击“确定”使用 SSH，点击“取消”使用 Telnet") ? "ssh" : "telnet";

			fetch('configure_snmp.php', {
				method: 'POST',
				headers: {'Content-Type': 'application/json'},
				body: JSON.stringify({ ip, username, password, community, zabbix_server: zabbixServer, protocol })
			})
			.then(res => res.json())
			.then(data => {
				if (data.success) {
					alert("SNMP 配置成功！");
				} else {
					alert("配置失败：" + data.error);
				}
			});
		}
		function updateInputs() {
            const currentType = $('#netType').val();
            
            if(currentType ==='1'){
				$('#netDevice').show();
			} else {
				$('#netDevice').hide();
			}
            
        }
	</script>
</head>

<body>
	<form method="post">
		<input type="text" name="subnet" placeholder="e.g. 192.168.1.0/24" required>
		<input type="submit" value="扫描">
	</form>
	<div class="modal-backdrop" id="modalBackdrop"></div>
	<div id="modalContainer" class="modal-container">		
		<div class="modal-close" id="closeModal"></div>
		<div class="modal-content">
			<h5 class="modal-title" id="myModalLabel"></h5>
			<div class="modal-body">
				<form id="myForm"> <!-- 表单 -->
					<input type="hidden" id="iptext",name="iptext">
					<input type="hidden" id="netType",name="netType">
					用户名: <input type="text" id="name" name="name"><br>
					密码: <input type="password" class="form-control password" autocomplete="off"id="pwd" name="pwd"><br>
					<div id="netDevice">
						<h5>请输入 SNMP community（如 public）：</h5>
							<input type="text" name="community" id="community" value="public"><br>
						<h5>Zabbix Server：</h5>
							<input type="text" id="zabbixServer" name="zabbixServer" placeholder="请输入 Zabbix Server地址"><br>
						
							<div class="radio-group">
								<h5>连接方式</h5>
								<label>
									<input type="radio" name="protocol" value="ssh" checked>
									<span class="custom-radio"></span>
									SSH
								</label>
								<label>
									<input type="radio" name="protocol" value="telnet" >
									<span class="custom-radio"></span>
									telnet
								</label>
							</div>
					
					</div>
				</form>
			</div>
			<div class="modal-footer">
				<button class="modal-btn btn-cancel" id="cancelBtn">取消</button>
				<button class="modal-btn btn-confirm" id="confirmBtn">确定</button>
			</div>
		</div>
	</div>
	
	
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['subnet'])) {
    $subnet = escapeshellarg($_POST['subnet']);
    $logfile = '/tmp/scan_debug.log';
    file_put_contents($logfile, "Calling scan.py with subnet: $subnet\n", FILE_APPEND);
	
    $output = shell_exec("sudo python3 /usr/lib/zabbix/scripts/nmap_scan.py $subnet");
	
    file_put_contents($logfile, "Output:\n$output\n", FILE_APPEND);
    $devices = json_decode($output, true);
    if (!empty($devices)) {
        echo "<h3>扫描结果</h3><table class= 'list-table' cellpadding='5'>";
        echo "<tr><th>IP</th><th>类型</th><th>MAC地址</th><th>厂商</th><th>登录</th></tr>";
        foreach ($devices as $dev) {
            $ip = htmlspecialchars($dev['ip']);
            $type = htmlspecialchars(strtolower($dev['type']));
            $mac = htmlspecialchars($dev['mac'] ?? 'N/A');
            $vendor = htmlspecialchars($dev['vendor'] ?? 'Unknown');
            #$ping = htmlspecialchars($dev['ping'] ?? 'N/A');

            echo "<tr>";
            echo "<td>$ip</td>";
            echo "<td>$type</td>";
            echo "<td>$mac</td>";
            echo "<td>$vendor</td>";
            #echo "<td>$ping</td>";
			echo "<td>";
            if ($type === 'linux') {
                echo "<button  class='install'  data-ip='$ip' data-type='0' >登录</button>";
            } elseif ($type === 'windows') {
                echo "<button onclick=\"showWindowsLoginTip()\">登录</button>";
            } elseif ($type === 'network') {
                echo "<button class='install'  data-ip='$ip' data-type='1'>登录</button>";
            }else {
                echo "<button disabled>不支持</button>";
            }
            echo "</td>";
            echo "</tr>";
        }
        echo "</table>";
    } else {
        echo "<p>No devices found.</p>";
    }
}
?>


</body>
</html>
